﻿
namespace LightCAD.Drawing.Actions
{

    public class UCSAction 
    {

        public static string CommandName;
        public static LcCreateMethod[] CreateMethods;
        protected CancellationTokenSource cts;
        protected bool isFinish;
        protected DocumentRuntime docRt;
        protected ViewportRuntime vportRt;

        private string blockName;
        private string CurrentTransform;
        private Vector2 insertPoint;
        private Vector2 basePoint;
        private List<LcElement> selectedElements;

        private InElementsInputer InElementsInputer { get; set; }
        private ElementSetInputer ElementInputers { get; set; }
        private ElementInputer ElementInputer { get; set; }
        private CmdTextInputer CmdTextInputer { get; set; }
        private PointInputer PointInputer { get; set; }
        static UCSAction()
        {
            //if (command.Name.ToUpper() == "OPENUCS")
            //{
            //    this.Viewport.Ucs.Set(new Vector2d(100, 100), new Vector2d(1, 1).Normalized, new Vector2d(-1, 1).Normalized);
            //}
            //else if (command.Name.ToUpper() == "CLOSEUCS")
            //{
            //    this.Viewport.Ucs.SetIdentity();
            //}
            //else if (command.Name.ToUpper() == "PLANUCS")
            //{
            //    this.Viewport.Ucs.IsPlan = true;
            //}
            //else if (command.Name.ToUpper() == "NORMALUCS")
            //{
            //    this.Viewport.Ucs.IsPlan = false;
            //}
            CreateMethods = new LcCreateMethod[4];
            CreateMethods[0] = new LcCreateMethod()
            {
                Name = "OPENUCS",
                Description = "打开用户坐标系",
                Steps = new LcCreateStep[]
                {
                    new LcCreateStep { Name=  "Step0", Options= "OPENUCS 选择对象:" },
                    new LcCreateStep { Name=  "Step1", Options= "OPENUCS 指定基点:" },
                    new LcCreateStep { Name=  "Step2", Options= "OPENUCS 指定X轴:" },
                    new LcCreateStep { Name=  "Step3", Options= "OPENUCS 指定参照长度:" },
                    new LcCreateStep { Name=  "Step4", Options= "OPENUCS 指定新的长度或 [点(P)]:" },
                    new LcCreateStep { Name=  "Step4", Options= "OPENUCS 指定第一点:" },
                    new LcCreateStep { Name=  "Step4", Options= "OPENUCS 指定第二点:" },
                }
            };
             
        }
        protected IDocumentEditor docEditor;
        protected ICommandControl commandCtrl;
        protected CommandCenter commandCenter;
        public UCSAction(IDocumentEditor docEditor)
        {
            this.vportRt = (docEditor as DrawingEditRuntime).ActiveViewportRt;
           

        }
        public UCSAction()
        {
          
        }

        public UCSAction SetViewport(ViewportRuntime vportRt)
        {
            this.vportRt = vportRt;
            this.docEditor = vportRt.DocEditor;
            this.docRt = docEditor.DocRt;
            this.commandCtrl = this.vportRt.CommandCtrl;
            this.commandCenter = this.vportRt.CommandCenter;
            return this;
        }

        public async void OPENUCS(string[] args)
        {
            this.StartAction();
            this.CurrentTransform = "SCALE";
            Vector2 scalePonit = new Vector2();
            var curMethod = CreateMethods[0];
            bool copy = false;
            this.ElementInputers = new ElementSetInputer(this.docEditor);
            this.CmdTextInputer = new CmdTextInputer(this.docEditor);
            this.PointInputer = new PointInputer(this.docEditor);
            // List<LcElement> SelectedElements = new List<LcElement>();
            double length = 0;
  


            
            Step1:
            var step1 = curMethod.Steps[1];
            var result1 = await PointInputer.Execute(step1.Options);

            if (PointInputer.isCancelled)
            {
                this.Cancel();
                return;
            }

            // zcb: 增加Res0为空的判定
            if (result1 == null)
            {
                this.Cancel();
                return;
            }

            if (result1.ValueX == null)
            {
                if (result1.Option != null)
                {
                    //TODO:AutoCAD画线输入一个数字，是怎么确定点的？
                }
                else
                    goto Step1;
            }
            this.basePoint = (Vector2)result1.ValueX;
            goto Step2;
            Step2:
         
            var step2 = curMethod.Steps[2];
            var result2 = await PointInputer.Execute(step2.Options);
            if (PointInputer.isCancelled)
            {
                this.Cancel();
                return;
            }
            if (result2.Option != null)
            {
                if (result2.Option.ToUpper() == "C")
                {
                    copy = true;
                    goto Step2;
                }
                length = Convert.ToDouble(result2.Option.ToString());
          
            }
            else
                scalePonit = (Vector2)result2.ValueX;
         
            goto End;
            End:
            //var mp = this.vportRt.PointerMovedPosition.ToVector2d();
            //var wcs_mp = this.vportRt.ConvertScrToWcs(mp);
            // Vector2d.Angle(new Vector2d(1, 0), new Vector2d(0, 1));
            ;
            var rotateAngle = Vector2.GetAngle(basePoint, new Vector2(basePoint.X ,basePoint.Y+100));
 
            Matrix3 matrix3 = Matrix3.RotateInRadian(rotateAngle, basePoint);

            //var X = basePoint.X - (scalePonit.Y- basePoint.Y);
            //var Y = basePoint.Y + (scalePonit.X- basePoint.X);
          // Matrix3 matrix31 = Matrix3.Move(basePoint, new Vector2d(0,0));
            Matrix3 matrix31 = Matrix3.GetMove(basePoint, new Vector2(0, 0));
            this.vportRt.Viewport.Ucs.Set(basePoint, matrix31.MultiplyPoint(scalePonit).Normalize(), matrix31.MultiplyPoint(matrix3.MultiplyPoint(scalePonit)).Normalize());
            // this.vportRt.Viewport.Ucs.Set(basePoint, matrix31.MultiplyPoint(scalePonit).Normalized, new Vector2d(-matrix31.MultiplyPoint(scalePonit).X, matrix31.MultiplyPoint(scalePonit).Y).Normalized);
            //  this.vportRt.Viewport.Ucs.Set(new Vector2d(100, 100), new Vector2d(1, 1).Normalized, new Vector2d(-1, 1).Normalized);
            //this.vportRt.Viewport.Ucs.Set(basePoint, scalePonit.Normalized, new Vector2d(X,Y).Normalized);

            //   this.vportRt.Viewport.Ucs.Set(new Vector2d(-133, -184.5), new Vector2d(48, -119.5).Normalized, new Vector2d(-198, -3.5).Normalized);

            this.vportRt.ResetCoordMatrix();
            this.EndAction();
          
        }
    
        private Vector2 PointRotate(Vector2 center, Vector2 p1, double angle)
        {
            double x1 = (p1.X - center.X) * Math.Cos(angle) + (p1.Y - center.Y) * Math.Sin(angle) + center.X;
            double y1 = -(p1.X - center.X) * Math.Sin(angle) + (p1.Y - center.Y) * Math.Cos(angle) + center.Y;

            return new Vector2(x1, y1);
        }
 
        public void DrawUCS(SKCanvas canvas)
        {
            var mp = this.vportRt.PointerMovedPosition.ToVector2d();
            var wcs_mp = this.vportRt.ConvertScrToWcs(mp);
            var Angle = Vector2.GetAngle(basePoint, wcs_mp);
            Matrix3 matrix3 = Matrix3.RotateInRadian(Angle, basePoint);
            DrawAuxLine(canvas);
            foreach (var item in selectedElements)
            {
                var eleAction = (item.RtAction as ElementAction);
                eleAction.Draw(canvas, item, matrix3);
            }

        }
        public void DrawAuxLine(SKCanvas canvas)
        {
            var mp = this.vportRt.PointerMovedPosition.ToVector2d();
            var wcs_mp = this.vportRt.ConvertScrToWcs(mp);
            var sk_pre = this.vportRt.ConvertWcsToScr(basePoint).ToSKPoint();
            var sk_p = this.vportRt.ConvertWcsToScr(wcs_mp).ToSKPoint();
            SKPaint AuxPen = new SKPaint { Color = SKColors.Gray, IsStroke = true, PathEffect = Constants.SelectedEffect };
            canvas.DrawLine(sk_pre, sk_p, AuxPen);
        }
        private void OnInputKeyUp(KeyEventRuntime runtime)
        {
            throw new NotImplementedException(); 
        }

        private void OnInputKeyDown(KeyEventRuntime runtime)
        {
            throw new NotImplementedException();
        }

        private void OnViewportKeyDown(KeyEventRuntime runtime)
        {
            throw new NotImplementedException();
        }

        private void OnViewportMouseEvent(string arg1, MouseEventRuntime runtime)
        {
            throw new NotImplementedException();
        }

        protected void DetachEvents()
        {

            //    vportRt.Control.DetachEvents(this.OnViewportMouseEvent, this.OnViewportKeyDown);
            //docRt.Commander.DetachInputEvent(OnInputKeyDown, OnInputKeyUp);
        }
        public void Cancel()
        {
            this.DetachEvents();
            //TODO:
            this.EndAction();
        }
        public void StartAction()
        {
            var vportRt = this.vportRt;
            if (vportRt.CheckStatus(ViewportStatus.InAction))
            {
                vportRt.CancelCurrentAction();
            }
            vportRt.SetStatus(ViewportStatus.InAction);
            this.commandCenter.InAction = true;
        }
        public void EndAction()
        {
            var vportRt = this.vportRt;
            vportRt.ClearStatus();
            this.commandCtrl.Prompt(string.Empty);
 
            this.vportRt.CurrentAction = null;
            this.vportRt.CursorType = LcCursorType.SelectElement;
            this.vportRt.CursorAddon = CursorAddonType.None;
            this.commandCenter.InAction = false;
            this.vportRt.CancelCurrentAction();
            if (this.docRt.Action.SelectedElements.Count > 0)
            {
                this.docRt.Action.SetSelectsToDragging(false);
                this.vportRt.ClearElementGrips();
                this.docRt.Action.ClearSelects();
            }
        }
    }


}


